import tsl_backend.jwt as jwt
import requests

# from django.contrib.auth.hashers import make_password
from tsl_backend.users.models import (
    User,
    Account,
    Printer,
    Role,
    Department,
    Site,
    Flow,
)
import tsl_backend.frontend_api.models.workorder as workorders
from tsl_backend.fgr_api.serializers import serializers as fgr_serializers
import logging

from django.conf import settings
from django.core.cache import cache
from django.templatetags.static import static


class FGR_Client:
    def __init__(self):
        self.host = settings.FGR_MIDDLEWARE_ENDPOINT
        self.FGR_TIMEOUT = settings.FGR_TIMEOUT

        self.token = self.__get_fgr_token()

    def __getHeaders(self):
        return {
            "authorization": self.__get_fgr_token(),
            "Content-Type": "application/json-patch+json",
        }

    def __get_fgr_token(self):
        # get and save token to cache
        # refresh token every 14 mins
        token = cache.get("fgr_token")

        FGR_MIDDLEWARE_USERNAME = settings.FGR_MIDDLEWARE_USERNAME
        FGR_MIDDLEWARE_PASSWORD = settings.FGR_MIDDLEWARE_PASSWORD

        if not token:
            logging.info("Send request to FGR to get token")
            # Get a new token from the API
            url = "/User/getToken"
            data = {
                "userName": FGR_MIDDLEWARE_USERNAME,
                "password": FGR_MIDDLEWARE_PASSWORD,
            }
            headers = {"Content-Type": "application/json-patch+json"}

            res = self.send_request("post", url, json_data=data, headers=headers)

            if res["status"] == True:
                token = "Bearer " + res["data"]

                # Store the token in cache with a timeout of 14 minutes
                cache.set("fgr_token", token, timeout=840)

            else:
                logging.info("Fail to get token from FGR{}".format(res["message"]))

        return token

    def send_request(self, method, url, json_data=None, data=None, headers=None, content_type=None):
        if not headers:
            headers = self.__getHeaders()
            
        if content_type:
            headers["Content-Type"]=content_type
        # logging.info(f"Send {method} request to FGR {self.host + url}: {data}")
        json_response = {"status": False, "code": "", "message": "", "data": ""}
        # json_data = {'userName': 'FGRAPI', 'password': '123456'}
        try:
            if json_data:
                response = requests.request(method, self.host + url, json=json_data, headers=headers, timeout=self.FGR_TIMEOUT)
            if data:
                response = requests.request(method, self.host + url, data=data, headers=headers, timeout=self.FGR_TIMEOUT)
            json_response = response.json()
        except requests.exceptions.HTTPError as http_error:
            logging.error(f"HTTP error occurred: {http_error}")
            json_response["message"] = "HTTP error occurred"
        except requests.exceptions.ConnectionError as connection_error:
            logging.error(f"Connection error occurred: {connection_error}")
            json_response["message"] = "Connection error occurred"
        except requests.exceptions.Timeout as timeout_error:
            logging.error(f"Request timed out: {timeout_error}")
            json_response["message"] = "Request timed out"
            json_response["code"] = 408
        except requests.exceptions.RequestException as request_exception:
            logging.error(f"An error occurred: {request_exception}")
            json_response["message"] = "An error occurred"
            json_response["code"] = 500
        except Exception as e:
            logging.error(f"Excecption occurred: {e}")
            json_response["code"] = 500
            json_response["message"] = "Excecption occurred"

        logging.info(f"Response from FGR {json_response}")
        return json_response


fgr_client = FGR_Client()

def queryColorImgs(order, content_type):
    url = "/ewo_prodorder/queryColorImgs"
    data = {"orderNo": order}
    logging.info(f"Send request to {url}: {data}")
    res = fgr_client.send_request("post", url, data=data, content_type=content_type)
    return res


def queryStoneImgs(order, content_type):
    url = "/ewo_prodorder/queryStoneImgs"
    data = {"orderNo": order}
    logging.info(f"Send request to {url}: {data}")
    res = fgr_client.send_request("post", url, data=data, content_type=content_type)
    return res


def queryReportParams(report_type, staffcode, usercode):
    data = {"reportType": report_type, "staffId": staffcode, "userCode": usercode}
    url = "/ewo_report/queryReportParams"

    logging.info(f"Send request to {url}: {data}")
    res = fgr_client.send_request("post", url, json_data=data)

    if res["status"] == True:
        if res["code"] != "200":
            logging.info(f"code is not 200: {res['code']}")
    else:
        logging.info(f"Fail to get report params")

    return res


def queryReportResult(report_type, staffcode, usercode, gold_type, date_from, date_to):
    url = "/ewo_report/queryReportResult"
    data = {
        "reportType": report_type,
        "staffId": staffcode,
        "userCode": usercode,
        "nk": gold_type,
        "dateFrom": date_from if date_from  else '',
        "dateTo": date_to if date_to else '',
    }
    
    logging.info(f"Send request to {url}: {data}")
    res = fgr_client.send_request("post", url, json_data=data)

    if res["status"] == True:
        if res["code"] != "200":
            logging.info(f"code is not 200: {res['code']}")
    else:
        logging.info(f"Fail to get report params")
        logging.info(f"{res['message']}")

    return res

    # test data
    # if report_type=="storage":
    #     res={
    #         "status": True,
    #         "code": "200",
    #         "message": "查询报表数据成功",
    #         "data": "\"{\\\"ReportType\\\":\\\"storage\\\",\\\"data\\\":{\\\"WorkerLocMstr\\\":[{\\\"dptcde\\\":\\\"B3E0244\\\",\\\"stkcde\\\":\\\"G750  \\\",\\\"Quanty\\\":88.090}],\\\"WorderLocDet\\\":[{\\\"sonum\\\":\\\"散金\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":1.010,\\\"stoneitm\\\":\\\"\\\",\\\"stoneqty\\\":\\\"\\\"},{\\\"sonum\\\":\\\"200000434353\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":2.720,\\\"stoneitm\\\":\\\"34\\\",\\\"stoneqty\\\":\\\"0.600\\\"},{\\\"sonum\\\":\\\"200000434800\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":4.880,\\\"stoneitm\\\":\\\"120\\\",\\\"stoneqty\\\":\\\"0.508\\\"},{\\\"sonum\\\":\\\"200000434926\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":4.460,\\\"stoneitm\\\":\\\"54\\\",\\\"stoneqty\\\":\\\"0.387\\\"},{\\\"sonum\\\":\\\"200000435392\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":13.320,\\\"stoneitm\\\":\\\"70\\\",\\\"stoneqty\\\":\\\"0.743\\\"},{\\\"sonum\\\":\\\"200000435409\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":2.130,\\\"stoneitm\\\":\\\"54\\\",\\\"stoneqty\\\":\\\"0.405\\\"},{\\\"sonum\\\":\\\"200000435560\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":0.710,\\\"stoneitm\\\":\\\"18\\\",\\\"stoneqty\\\":\\\"0.137\\\"},{\\\"sonum\\\":\\\"200000436480\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":13.430,\\\"stoneitm\\\":\\\"225\\\",\\\"stoneqty\\\":\\\"0.622\\\"},{\\\"sonum\\\":\\\"200000436546\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":6.530,\\\"stoneitm\\\":\\\"3\\\",\\\"stoneqty\\\":\\\"1.078\\\"},{\\\"sonum\\\":\\\"200000436547\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":6.630,\\\"stoneitm\\\":\\\"3\\\",\\\"stoneqty\\\":\\\"1.058\\\"},{\\\"sonum\\\":\\\"200000436654\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":3.770,\\\"stoneitm\\\":\\\"90\\\",\\\"stoneqty\\\":\\\"0.679\\\"},{\\\"sonum\\\":\\\"200000437049\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":14.070,\\\"stoneitm\\\":\\\"75\\\",\\\"stoneqty\\\":\\\"0.420\\\"},{\\\"sonum\\\":\\\"200000437103\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":10.740,\\\"stoneitm\\\":\\\"56\\\",\\\"stoneqty\\\":\\\"0.576\\\"},{\\\"sonum\\\":\\\"200000437119\\\",\\\"stkdesc\\\":\\\"G750  \\\",\\\"quanty\\\":3.690,\\\"stoneitm\\\":\\\"90\\\",\\\"stoneqty\\\":\\\"0.680\\\"}],\\\"WorkerSum\\\":[{\\\"TotalOrdnum\\\":13,\\\"TotalOrdqty\\\":43.000}]}}\"",
    #         "extra": None,
    #         "extras": None
    #         }

    # elif report_type=="transaction":
    #     res={
    #         "status": True,
    #         "code": "200",
    #         "message": "查询报表数据成功",
    #         "data": "{\\\"ReportType\\\":\\\"transaction\\\",\\\"data\\\":{\\\"WorkerTrx\\\":[{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":1,\\\"out_date\\\":\\\"2023-04-20\\\",\\\"sonum\\\":\\\"300000080792\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.180,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.160,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":2,\\\"out_date\\\":\\\"2023-04-20\\\",\\\"sonum\\\":\\\"300000080793\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.110,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.090,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":3,\\\"out_date\\\":\\\"2023-04-20\\\",\\\"sonum\\\":\\\"300000080797\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.060,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.050,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.010},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":4,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"300000080791\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.150,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.130,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":5,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"300000080796\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":7.980,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":7.960,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":6,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"300000080799\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.200,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.180,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":7,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"散金\\\",\\\"designno\\\":\\\"\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":0.000,\\\"out_fgwgt\\\":4.290,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":4.290,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.000}]}}",
    #         "extra": None,
    #         "extras": None
    #         }

    # else:
    #     res={
    #         "status": True,
    #         "code": "200",
    #         "message": "查询报表数据成功",
    #         "data": "{\\\"ReportType\\\":\\\"handset\\\",\\\"data\\\":{\\\"WorkerTrx\\\":[{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":1,\\\"out_date\\\":\\\"2023-04-20\\\",\\\"sonum\\\":\\\"300000080792\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.180,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.160,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":2,\\\"out_date\\\":\\\"2023-04-20\\\",\\\"sonum\\\":\\\"300000080793\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.110,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.090,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":3,\\\"out_date\\\":\\\"2023-04-20\\\",\\\"sonum\\\":\\\"300000080797\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.060,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.050,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.010},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":4,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"300000080791\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.150,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.130,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":5,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"300000080796\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":7.980,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":7.960,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":6,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"300000080799\\\",\\\"designno\\\":\\\"AG9261E\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":5.000,\\\"out_fgwgt\\\":8.200,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":8.180,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.020},{\\\"wrkdpt\\\":\\\"B3E0244\\\",\\\"RowID\\\":7,\\\"out_date\\\":\\\"2023-04-21\\\",\\\"sonum\\\":\\\"散金\\\",\\\"designno\\\":\\\"\\\",\\\"stkcde\\\":\\\"PT950\\\",\\\"qty\\\":0.000,\\\"out_fgwgt\\\":4.290,\\\"stoneqty\\\":0,\\\"stonewgt\\\":0.000,\\\"in_date\\\":\\\"2023-04-21\\\",\\\"in_fgwgt\\\":4.290,\\\"scrap\\\":0.000,\\\"fgwgt\\\":0.000}]}}",
    #         "extra": None,
    #         "extras": None
    #         }


def printLabelByOrderNo(orders, printer_id, site, groupId, staffId, userCode):
    logging.info(f"Send order no to print label")
    url = "/ewo_prodorder/printLabelByOrderNo"
    data={
            "orders": orders,
            "printerId": printer_id,
            "siteCode": site,
            "groupId": groupId,
            "staffId": staffId,
            "userCode": userCode
        }

    logging.info(f"Send {data} to {url}")
    res = fgr_client.send_request("post", url, json_data=data)

    logging.info(f"Response from FGR: {res}" )

    return res


def eorderAuth(staffId, pwd):
    # if settings.DEBUG:
    #     logging.info(f"Development user!!!!!!!!!!")
    #     return "", User.objects.get(username=staffId)

    logging.info(f"Send user [{staffId}] to FGR for authentication")
    url = "/ewo_staff/loginEOrder"
    data = {
        "staffId": staffId,
        "pwd": pwd,
    }
    res = fgr_client.send_request("post", url, json_data=data)

    # if staffId == "GNS001":
    res["status"] = True
    res["data"] = {}
    res["data"]["staffInfo"] = {
        "staffID":staffId,
        "cnName": "查冬日"
    }
    # 11001592 执摸一 组长
    # 15000413 QC
    # 11001762 工人
    if res["status"]:
        logging.info(f"Authentication success for user {staffId}")
        data = res["data"]
        logging.info(f"user detail: {data}")
        staffInfo = data["staffInfo"]
        # depts = staffInfo["depts"]
        user, user_created = User.objects.get_or_create(
            username=staffId,
            defaults={
                "password": User.objects.make_random_password(),
                "staffcode": staffInfo["staffID"],
                "cnName": staffInfo["cnName"],
                "is_active": True,
                "is_staff": False,
                "is_superuser": False,
            },
        )

        # user.staffcode = staffInfo["staffID"]
        # user.cnName = staffInfo["cnName"]
        # user.is_active = True
        # user.save()

        # logging.info(f"Update user {staffId} staffcode and cnName")

        # update_count = Account.objects.filter(django_user=user).update(enable=False)
        # logging.info(f"Reset {update_count} accounts for user {user}")

        # for dept in depts:
        #     role_obj, _ = Role.objects.get_or_create(name=dept["role"])
        #     site_obj, _ = Site.objects.get_or_create(name=dept["source"])
        #     flow_obj, _ = Flow.objects.get_or_create(
        #         name=dept["flow"],
        #         defaults={
        #             "leader_check": False,
        #             "stone_exam": False,
        #             "scan_and_record": False,
        #             "qc_check": False,
        #         },
        #     )
        #     department_obj, _ = Department.objects.get_or_create(
        #         code=dept["deptCode"],
        #         defaults={"name": dept["deptName"], "site": site_obj, "flow": flow_obj},
        #     )
        #     account, created_account = Account.objects.update_or_create(
        #         user_code=dept["userCode"],
        #         django_user=user,
        #         department=department_obj,
        #         role=role_obj,
        #         defaults={"default_printer": Printer.objects.first(),
        #                   "enable":True},

        #     )


            # account.role.add(role_obj)

        message = "Success"

    else:
        logging.info(f"Authentication fail for user {staffId}")
        message = f"Authentication fail for user {staffId} ({res['message']})"
        user = None

    return message, user


def updatePwd(staffcode, oldPWD, newPWD, resetMode):
    logging.info(f"Send request to FGR for pawword update of staffId {staffcode}")
    url = "/ewo_staff/updatePwd"
    data = {
        "staffId": staffcode,
        "oldPWD": oldPWD,
        "newPWD": newPWD,
        "resetMode": resetMode,
    }
    logging.info(f"data: {data}")
    res = fgr_client.send_request("post", url, json_data=data)

    if res["status"] == True:
        if res["code"] != "200":
            logging.info(f"code is not 200: {res}")
            return False
        logging.info(f"Success to update password: {res}")
        return True
    else:
        logging.info(f"Fail to update password: {res}")
        return False

def queryActualBom(orderNo, source):
    logging.info(f"Query actual bom of order {orderNo} - {source}")
    url = "/ewo_prodorder/queryActualBom"
    data = {
        "OrderNo": orderNo,
        "Source": source,
    }
    logging.info(f"Send {data} to {url}")
    res = fgr_client.send_request("post", url, json_data=data)
    logging.info(f"return from fgr: {res}")
    instances=None

    if res["code"] == "200":
        data = res["data"]
        logging.info(f"Actual bom data: {data}")
        message = "Success"

        if data:
            TotalCount = data["totalCount"] if "totalCount" in data else None
            TotalCT = data["totalCT"] if "totalCT" in data else None
            TotalGram = data["totalGram"] if "totalGram" in data else None
            stoneIssue = data["stoneIssue"] if "stoneIssue" in data else None
            Huatou = data["Huatou"] if "Huatou" in data else None

            logging.info(f"Create actualbom for order {orderNo}")

            # update count in Detail
            detail_obj = workorders.Detail.objects.get(order=orderNo)
            detail_obj.total_count = TotalCount
            detail_obj.total_ct = TotalCT
            detail_obj.total_gram = TotalGram
            detail_obj.stone_issue = stoneIssue
            if Huatou:
                detail_obj.flower_count = Huatou
            detail_obj.save()
            logging.info(
                f"Update total_count, total_ct and total_gram for order {orderNo}"
            )
            if data["actualBomMappings"]:
                actualBomMappings = data["actualBomMappings"]
                for bom_mapping in actualBomMappings:
                    # Add the workorder ID to the dictionary
                    bom_mapping["workorder"] = orderNo

                    # Create a validated serializer instance for the dictionary
                    # print(bom_mapping)
                serializer = fgr_serializers.ActualBomSerializer(data=actualBomMappings, many=True)

                # If the serializer is valid, create a new ProductionActualBOM instance and add it to the list
                if serializer.is_valid():
                    instances=serializer.save()
                else:
                    logging.info(f"ActualBomSerializer is not valid")
                    logging.error(f"{serializer.errors} for order {orderNo}.")

            else:
                logging.info(f"No actual bom for {orderNo}")

    else:
        logging.info(f"Fail to query actual bom for order {orderNo}")
        message = f"Fail to query actual bom for order {orderNo} ({res['message']})"

    return message, instances


# Test only
from rest_framework.decorators import api_view
from rest_framework.response import Response


@api_view()
def call_queryStoneImgs(request):
    order = request.GET.get("order")
    res = queryStoneImgs(order)
    return Response(res)


@api_view()
def call_queryColorImgs(request):
    order = request.GET.get("order")
    res = queryColorImgs(order)
    return Response(res)


@api_view()
def call_queryReportParams(request):
    report_type = request.GET.get("report_type")
    staffcode = request.GET.get("staffcode")
    usercode = request.GET.get("usercode")
    res = queryReportParams(report_type, staffcode, usercode)
    return Response(res)


@api_view()
def call_queryReportResult(request):
    report_type = request.GET.get("report_type")
    staffcode = request.GET.get("staffcode")
    usercode = request.GET.get("usercode")
    gold_type = request.GET.get("gold_type")
    date_from = request.GET.get("date_from")
    date_to = request.GET.get("date_to")

    res = queryReportResult(
        report_type, staffcode, usercode, gold_type, date_from, date_to
    )

    return Response(res)


@api_view()
def call_printLabelByOrderNo(request):
    order = request.GET.get("order")
    printer_id = request.GET.get("printer_id")
    site = request.GET.get("site")
    group = request.GET.get("group")
    description = request.GET.get("description")
    department = request.GET.get("department")
    res = printLabelByOrderNo(order, printer_id, site, group, description, department)
    return Response(res)
